package org.zhadoop.stream.cql.semanticanalyzer;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zhadoop.stream.api.streams.Schema;
import org.zhadoop.stream.cql.exception.SemanticAnalyzerException;
import org.zhadoop.stream.cql.semanticanalyzer.analyzecontext.AnalyzeContext;
import org.zhadoop.stream.cql.semanticanalyzer.analyzecontext.FromClauseAnalyzeContext;
import org.zhadoop.stream.cql.semanticanalyzer.analyzecontext.expressiondesc.ExpressionDescribe;
import org.zhadoop.stream.cql.semanticanalyzer.analyzecontext.expressiondesc.StreamAliasDesc;
import org.zhadoop.stream.cql.semanticanalyzer.parser.context.DataSourceBodyContext;
import org.zhadoop.stream.cql.semanticanalyzer.parser.context.FromClauseContext;
import org.zhadoop.stream.cql.semanticanalyzer.parser.context.FromSourceContext;
import org.zhadoop.stream.cql.semanticanalyzer.parser.context.JoinRigthBodyContext;
import org.zhadoop.stream.cql.semanticanalyzer.parser.context.ParseContext;
import org.zhadoop.stream.cql.semanticanalyzer.parser.context.SelectStatementContext;
import org.zhadoop.stream.cql.semanticanalyzer.parser.context.StreamBodyContext;

/**
 * from 子句语法分析
 * @author zwd
 *
 */
public class FromClauseAnalyzer extends BaseAnalyzer {

	private static final Logger LOG = LoggerFactory.getLogger(FromClauseAnalyzer.class);
	
	private FromClauseAnalyzeContext analyzeContext;
	
	private FromClauseContext fromContext;
	

	public FromClauseAnalyzer(ParseContext parseContext) throws SemanticAnalyzerException {
		super(parseContext);
		fromContext = (FromClauseContext) parseContext;
	}

	@Override
	public AnalyzeContext analyze() throws SemanticAnalyzerException {
		parseFromContext();
        return analyzeContext;
	}

	private void parseFromContext() throws SemanticAnalyzerException{
		/**
		 * 在多流进行join或者combine时候，要先计算最右边的流
		 */
		FromSourceContext left = fromContext.getSourceContext().getLeftStream();
		List<JoinRigthBodyContext> rights = fromContext.getSourceContext().getJoinRightBody();
		
		if(rights.size() == 0){
			parseFromSource(left);
            return;
		}
		parseJoinContext();
	}

	private void parseJoinContext() {
		// TODO Auto-generated method stub
		
	}

	private ExpressionDescribe parseFromSource(FromSourceContext from) throws SemanticAnalyzerException{
		if(from.getStreamBody() != null){
			return parseStreamBody(from.getStreamBody());
		}
		return parseDataSourceBody(from.getDataSoruceBody());
	}

	private ExpressionDescribe parseDataSourceBody(DataSourceBodyContext dataSoruceBody) {
		// TODO Auto-generated method stub
		return null;
	}

	private StreamAliasDesc parseStreamBody(StreamBodyContext from) throws SemanticAnalyzerException{
		String streamName = null;
		Schema schema = null;
		if(from.getStreamSource().getSubQuery() != null){
			streamName = createNewStreamName();
            schema = parseSubQuery(streamName, from.getStreamSource().getSubQuery());
		}else{
			streamName = from.getStreamSource().getStreamName();
            schema = getSchemaByName(streamName).cloneSchema();
		}
		
		boolean isUniDirect = from.isUnidirection();
		
		StreamAliasDesc salias = createStreamAliasDesc(from, streamName, schema);
		parseUnidirection(isUniDirect, salias);
		return salias;
	}

	private void parseUnidirection(boolean isUniDirect, StreamAliasDesc salias) {
		// TODO Auto-generated method stub
		
	}

	private Schema parseSubQuery(String streamName, SelectStatementContext subQuery) {
		return null;
	}

	private String createNewStreamName() {
		return null;
	}

	private StreamAliasDesc createStreamAliasDesc(StreamBodyContext from, String streamName, Schema schema) 
	throws SemanticAnalyzerException{
		StreamAliasDesc desc = new StreamAliasDesc();
		desc.setStreamName(streamName);
		String alias = from.getAlias();
		if(alias != null){
			desc.setStreamAlias(alias);
			schema.setName(alias);
		}
		analyzeContext.getInputSchemas().add(schema);
		
		//在多流Join的时候，会导致有schema 找不到
		//比如S1 join S2 on s1.id = s2.id join s3 on s1.id=s3.id
		//就会先解析右边S2和S3，这样S1的schema就找不到了
		//所以后期所有的parseContext 都要实现walk接口
		alias = alias == null ? streamName : alias;
		
		analyzeContext.addInputStream(alias);
		return desc;
	}

	@Override
	protected AnalyzeContext getAnalyzeContext() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	protected void createAnalyzeContext() {
		// TODO Auto-generated method stub
		
	}

}
